package com.tfswx.ocrengine.util;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.MediaType;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.lang.Nullable;
import org.springframework.web.client.RestTemplate;

import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Optional;

/**
 * @author Ricky
 * @date 2021/1/27
 */
@Slf4j
public class HttpUtil {
    private static final String SEND_LOG_PATTERN = "==>  {}  {}";

    private HttpUtil() {
    }

    public static RestTemplate getRestTemplate() {
        RestTemplate restTemplate = new RestTemplate();
        List<HttpMessageConverter<?>> messageConverters = restTemplate.getMessageConverters();
        Optional<HttpMessageConverter<?>> first = messageConverters.stream().filter(messageConverter -> messageConverter.getClass() == FastJsonHttpMessageConverter.class).findFirst();
        if (!first.isPresent()) {
            FastJsonHttpMessageConverter fastJsonHttpMessageConverter = new FastJsonHttpMessageConverter();
            List<MediaType> supportedMediaTypes = new ArrayList<>();
            supportedMediaTypes.add(MediaType.APPLICATION_JSON);
            supportedMediaTypes.add(MediaType.APPLICATION_JSON_UTF8);
            supportedMediaTypes.add(MediaType.APPLICATION_ATOM_XML);
            supportedMediaTypes.add(MediaType.APPLICATION_FORM_URLENCODED);
            supportedMediaTypes.add(MediaType.APPLICATION_OCTET_STREAM);
            supportedMediaTypes.add(MediaType.APPLICATION_PDF);
            supportedMediaTypes.add(MediaType.APPLICATION_RSS_XML);
            supportedMediaTypes.add(MediaType.APPLICATION_XHTML_XML);
            supportedMediaTypes.add(MediaType.APPLICATION_XML);
            supportedMediaTypes.add(MediaType.IMAGE_GIF);
            supportedMediaTypes.add(MediaType.IMAGE_JPEG);
            supportedMediaTypes.add(MediaType.IMAGE_PNG);
            supportedMediaTypes.add(MediaType.TEXT_EVENT_STREAM);
            supportedMediaTypes.add(MediaType.TEXT_HTML);
            supportedMediaTypes.add(MediaType.TEXT_MARKDOWN);
            supportedMediaTypes.add(MediaType.TEXT_PLAIN);
            supportedMediaTypes.add(MediaType.TEXT_XML);
            fastJsonHttpMessageConverter.setSupportedMediaTypes(supportedMediaTypes);
            messageConverters.add(fastJsonHttpMessageConverter);
        }
        return restTemplate;
    }

    public static <T> T postForObject(String url, @Nullable Object request, Class<T> responseType, Object... uriVariables) {
        long startTime = System.currentTimeMillis();
        try {
            return getRestTemplate().postForObject(url, request, responseType, uriVariables);
        } finally {
            log.info(SEND_LOG_PATTERN, url, System.currentTimeMillis() - startTime);
        }
    }

    public static <T> T getForObject(String url, @Nullable Object request, Class<T> responseType, Object... uriVariables) {
        Map<String, Object> map = JSON.parseObject(JSON.toJSONString(request));
        StringBuilder param = new StringBuilder();
        String s = "?";
        for (Map.Entry<String, Object> entry : map.entrySet()) {
            param.append(s).append(entry.getKey()).append("=").append(entry.getValue());
            s = "&";
        }
        long startTime = System.currentTimeMillis();
        try {
            return getRestTemplate().getForObject(url + param, responseType, uriVariables);
        } finally {
            log.info(SEND_LOG_PATTERN, url, System.currentTimeMillis() - startTime);
        }
    }

    public static <T> T getForObject(String url, Class<T> responseType, Object... uriVariables) {
        long startTime = System.currentTimeMillis();
        try {
            return getRestTemplate().getForObject(url, responseType, uriVariables);
        } finally {
            log.info(SEND_LOG_PATTERN, url, System.currentTimeMillis() - startTime);
        }
    }

    public static File downloadFile(String url, String filePath) {
        return downloadFile(url, filePath);
    }

    public static File downloadFile(String url, File file) {
        return getRestTemplate().execute(url, HttpMethod.GET, null, response -> {
            HttpHeaders headers = response.getHeaders();
            long contentLength = headers.getContentLength();
            File canonicalFile = file.getCanonicalFile();
            if (!canonicalFile.getParentFile().exists()) {
                boolean b = canonicalFile.getParentFile().mkdirs();
                if (!b) {
                    log.debug("创建失败");
                }
            }
            try (
                    FileOutputStream fileOutputStream = new FileOutputStream(canonicalFile);
                    InputStream inputStream = response.getBody()) {
                byte[] buffer = new byte[1024 * 1024];
                int len;
                while ((len = inputStream.read(buffer)) != -1) {
                    fileOutputStream.write(buffer, 0, len);
                }
            }
            return canonicalFile;
        });
    }

    public static void main(String[] args) {
        try {
            postForObject("http://192.168.2.227:8088/dzjzzz-service/api/ajDzjz/SaveOCRResult?aaa=bbb", null, String.class);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
